package edu.udo.sopra10.chaturaji.entities.transfer;

import java.util.HashMap;

import edu.udo.sopra10.chaturaji.entities.coordinates.Position;
import edu.udo.sopra10.chaturaji.entities.pieces.Boat;
import edu.udo.sopra10.chaturaji.entities.pieces.Elephant;
import edu.udo.sopra10.chaturaji.entities.pieces.Horse;
import edu.udo.sopra10.chaturaji.entities.pieces.King;
import edu.udo.sopra10.chaturaji.entities.pieces.Pawn;
import edu.udo.sopra10.chaturaji.util.ExceptionUtil;

/**
 * Piece transfer object.
 * 
 * @author Patrick Westerhoff
 */
public class Piece {
	/**
	 * Piece type.
	 * 
	 */
	public enum PieceType {
		BOAT, ELEPHANT, HORSE, KING, PAWN;
	}

	@SuppressWarnings("unchecked")
	private static final HashMap<Class, PieceType> PIECE_TYPES = new HashMap<Class, PieceType>();

	static {
		PIECE_TYPES.put(King.class, PieceType.KING);
		PIECE_TYPES.put(Elephant.class, PieceType.ELEPHANT);
		PIECE_TYPES.put(Horse.class, PieceType.HORSE);
		PIECE_TYPES.put(Boat.class, PieceType.BOAT);
		PIECE_TYPES.put(Pawn.class, PieceType.PAWN);
	}

	/**
	 * Constructs a transfer object using a Piece entity.
	 * 
	 * @param piece
	 *            the entity.
	 * @return the generated transfer object.
	 */
	public static Piece createFromEntity(
			final edu.udo.sopra10.chaturaji.entities.pieces.Piece piece) {
		return new Piece(piece.getOwner().getTurnOrderPosition(),
				getPieceTypeByPiece(piece), piece.getSquare().getPosition());
	}

	/**
	 * Returns the {@link PieceType} of the given piece.
	 * 
	 * @param piece
	 *            the piece.
	 * @return the piece type of the specified piece.
	 */
	public static PieceType getPieceTypeByPiece(
			final edu.udo.sopra10.chaturaji.entities.pieces.Piece piece) {
		ExceptionUtil.assertNotNull(piece, "piece");
		return PIECE_TYPES.get(piece.getClass());
	}

	private final PieceType pieceType;

	private final byte playerId;

	private final Position position;

	/**
	 * Constructs a new Piece transfer object with the given data.
	 * 
	 * @param playerId
	 *            player id of the piece's owner.
	 * @param pieceType
	 *            the piece type.
	 * @param position
	 *            the position of the piece.
	 */
	public Piece(final byte playerId, final PieceType pieceType,
			final Position position) {
		this.playerId = playerId;
		this.pieceType = pieceType;
		this.position = position;
	}

	/**
	 * Returns the type of the piece.
	 * 
	 * @return piece type.
	 */
	public PieceType getPieceType() {
		return pieceType;
	}

	/**
	 * Returns the id of the player.
	 * 
	 * @return player id.
	 */
	public byte getPlayerId() {
		return playerId;
	}

	/**
	 * Returns the position of the piece.
	 * 
	 * @return position of the piece.
	 */
	public Position getPosition() {
		return position;
	}
}